const { Client, LocalAuth } = require('whatsapp-web.js');
const path = require('path');
const fs = require('fs');
const erp_request = require('./erpauth').erp_request;
const uploadFileToOSS = require('./erpauth').uploadFileToOSS;

const userId = process.argv[2];
const chatId = process.argv[3];

if (!userId || !chatId) {
    console.error('错误: 未提供足够的参数。');
    console.error('用法: node sync_single_chat.js <userId> <chatId>');
    process.exit(1);
}

let client;

async function get_wc_config(_serialized) {
    const data = { _serialized: _serialized };
    console.log('获取配置: ' + _serialized);
    const response = await erp_request(data, 'wconfig', 'POST', 'crm/api/');
    if (!response.success) {
        console.log('获取微信配置失败');
        return false;
    }else {
        console.log('获取微信配置成功');
    }
    return response.data;
}

async function SyncChatMessage(chat, config) {
    console.log(`同步聊天: ${chat.name}`);
    let url = await client.getProfilePicUrl(chat.id._serialized);

    const chatData = {
        whatsappconfig__serialized: client.info.me._serialized,
        _serialized: chat.id._serialized,
        name: chat.name,
        avatar: url || '',
        isGroup: chat.isGroup,
        timestamp: chat.timestamp,
        unreadCount: chat.unreadCount,
        project_id: config.project_id,
        participants: [],
        messages: []
    };

    const media_messages = [];
    const text_messages = [];
    console.log('开始获取消息...');
    const messages = await chat.fetchMessages({limit: 50});
    for (let message of messages) {
        const fullpath = getFolderById(message.id.id);
        if (fs.existsSync(fullpath)) {
            continue;
        }
        console.log('消息发送者：', message.id.participant);
        const message_data = {
            id_message: message.id.id,
            message_from: message.from,
            message_to: message.to,
            hasMedia: message.hasMedia,
            body: message.body,
            timestamp: message.timestamp,
            links: message.links
        };
         if (message.id.participant !== undefined) {
            const participant = await client.getContactById(message.id.participant._serialized);
            // 如果chatData.participants 没有这个人就添加
            if (!chatData.participants.find(p => p._serialized === participant.id._serialized)){
                chatData.participants.push({
                    _serialized: participant.id._serialized,
                    isMe: participant.isMe,
                    name: participant.name,
                    shortName: participant.shortName,
                    pushname: participant.pushname,
                    isBusiness: participant.isBusiness,
                    number: participant.number
                })
              }
            message_data.message_from = message.id.participant._serialized
             try {
                const contact = await client.getContactById(message_data.message_from);
                console.log('Contact info:', contact);
            } catch (error) {
                console.error('Error getting contact:', error);
            }
        }
        if (message.hasMedia) {
            media_messages.push(message);
        } else {
            text_messages.push(message);
        }
        chatData.messages.push(message_data);
        console.log('获取消息:', message.id.id);
    }

    console.log('开始同步聊天到服务器...');
    let r = await erp_request(chatData, 'wcmessage', 'POST', 'crm/api/');
    if (r && r.success) {
        console.log('成功同步聊天');
        for (let id of text_messages.map(m => m.id.id)) {
            const fullpath = getFolderById(id);
            fs.writeFileSync(fullpath, '');
        }
    }

    if (r && r.success && r.media_ids) {
        for (let message of media_messages) {
            if (!r.media_ids.includes(message.id.id)) {
                continue;
            }
            console.log('获取媒体文件:', message.id.id);
            await handleMediaMessage(message, config, chat.id._serialized);
        }
    }
}

async function handleMediaMessage(message, config, chatId) {
    try {
        const media = await message.downloadMedia();
        if (!media || !media.data) {
            console.log('获取媒体文件失败');
            return;
        }

        const extension = getExtension(media.mimetype);
        const filename = message.id.id + '.' + extension;
        const message_data = {
            project_id: config.project_id,
            _serialized: chatId,
            id_message: message.id.id,
            content_type: media.mimetype,
            filename: filename,
            filesize: media.filesize
        };

        const mediaBuffer = Buffer.from(media.data, 'base64');
        const targetpath = config.oss_path + filename;
        const res = await uploadFileToOSS(mediaBuffer, targetpath, config.oss_config);
        console.log('文件上传成功');
        message_data.media_url = res.split('?')[0];
        message_data.oss_path = targetpath;
        await erp_request(message_data, 'wcmediamessage', 'POST', 'crm/api/');
    } catch (error) {
        console.error('处理媒体消息时出错:', error);
    }
}

function getFolderById(id) {
    const folder1 = id.substring(0, 1);
    const folder2 = id.substring(1, 2);
    const folder = folder1 + '/' + folder2;
    const filepath = path.join('./cache/', 'messages', folder);
    if (!fs.existsSync(filepath)) {
        fs.mkdirSync(filepath, { recursive: true });
    }
    const filename = id + '.txt';
    return path.join(filepath, filename);
}

function getExtension(mimetype) {
    // 保持原有的 getExtension 函数实现
    let extension = 'text';
    if (mimetype.startsWith('image/')) {
        extension = mimetype.split('/')[1];
    } else if (mimetype.startsWith('video/')) {
        extension = 'mp4';
    } else if (mimetype.startsWith('audio/')) {
        extension = mimetype.includes('opus') ? 'opus' : mimetype.split('/')[1];
    } else if (mimetype === 'application/pdf') {
        extension = 'pdf';
    } else if (mimetype === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
        extension = 'docx';
    } else if (mimetype === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
        extension = 'xlsx';
    }
    return extension;
}

async function initializeAndSync() {
    const config = await get_wc_config(userId + '@c.us')
    client = new Client({
        authStrategy: new LocalAuth({
            clientId: `client-${userId}`
        }),
        puppeteer: {
            headless: true,
            args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-gpu']
        },
         webVersion: "2.2412.54",
        webVersionCache: {
        type: "remote",
        remotePath:
          "https://raw.githubusercontent.com/wppconnect-team/wa-version/main/html/2.2412.54.html",
      }
    });
    console.log('正在初始化客户端...')
    client.on('loading_screen', (percent, message) => {
    console.log('LOADING SCREEN', percent, message);
    });

    client.on('authenticated', () => {
        console.log('AUTHENTICATED');
    });

    client.on('auth_failure', msg => {
        console.error('AUTHENTICATION FAILURE', msg);
    });

    client.on('ready', async () => {
        console.log('Client is ready!');
        try {
            const chat = await client.getChatById(chatId);
            await SyncChatMessage(chat, config);
        } catch (error) {
            console.error('同步聊天时出错:', error);
        } finally {
            console.log('同步完成，正在退出...');
            await client.destroy();
            process.exit(0);
        }
    });

    client.initialize().catch(error => {
    console.error('Error initializing client:', error);
    });
}

initializeAndSync().catch(error => {
    console.error('初始化客户端或同步过程中出错:', error);
    process.exit(1);
});
